package com.briup.emdc.config.impl;

import com.briup.emdc.client.Client;
import com.briup.emdc.client.Gather;
import com.briup.emdc.client.impl.ClientImpl;
import com.briup.emdc.client.impl.GatherImpl;
import com.briup.emdc.config.Backup;
import com.briup.emdc.config.Configuration;
import com.briup.emdc.config.Log;
import com.briup.emdc.server.DBStore;
import com.briup.emdc.server.Server;
import com.briup.emdc.server.impl.DBStoreImpl;
import com.briup.emdc.server.impl.ServerImpl;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * @author Kevin
 * @since 2024.04.11
 **/
public class ConfigurationImpl implements Configuration{
    public static final Map<String,Object> map;
    // private static final Map<String,WossModuleInit> map;
    private static final ConfigurationImpl conf;

    static{
        map=new TreeMap<>();
        conf=new ConfigurationImpl();
        try{
            SAXReader sr=new SAXReader();
            // doc对象代表那个config.xml文件
            Document doc=sr.read(ConfigurationImpl.class.getResourceAsStream("/config.xml"));
            // 获取该xml文档的根节点（根元素）
            Element re=doc.getRootElement();

            // 获取根节点的所有子节点（子元素）
            List<Element> ses=re.elements();

            // 创建Properties对象，用于存放从子节点中
            // 解析出来的所有属性
            Properties prop=new Properties();

            // 遍历ses，获取每一个子节点，
            // 从子节点中获取class属性的值，用于通过反射创建对象
            for(Element se: ses){
                // 然后获取子节点的子节点（X节点），让X节点的节点名
                // 作为属性名，让X节点的子节点值作为属性值
                List<Element> xes=se.elements();
                for(Element xe: xes){
                    String propName=xe.getName();
                    String propValue=xe.getStringValue();
                    prop.setProperty(propName,propValue);
                }
                // 下面是创建对象的过程
                Attribute attr=se.attribute("class");
                String className=attr.getStringValue();
                Class<?> clazz=Class.forName(className);
                // 本质是类类型，
                Object o=clazz.newInstance();
                // WossModuleInit w=(WossModuleInit)o;
                String classId=se.getName();
                // map.put(classId,w);
                map.put(classId,o);
            }
            for(Object o: map.values()){
                Class<?> clazz=o.getClass();
                Method initMethod=clazz.getMethod("init",Properties.class);
                initMethod.invoke(o,prop);

                Method configureMethod=clazz.getMethod("configure",Configuration.class);
                configureMethod.invoke(o,conf);
            }
            // for(Map.Entry<String,WossModuleInit> entry: map.entrySet()){
            //     WossModuleInit w=entry.getValue();
            //     w.init(prop);
            //     w.configure(conf);
            // }
        }catch(Exception e){
            Log log =(Log)map.get("logger");
            log.error(e.getMessage());
        }
    }

    private ConfigurationImpl(){
        if(conf!=null){
            throw new RuntimeException("不能重复创建对象！");
        }
    }

    public static ConfigurationImpl getInstance(){
        return conf;
    }

    @Override
    public Log getLogger(){
        return (LogImpl)map.get("logger");
    }

    @Override
    public Server getServer(){
        return (ServerImpl)map.get("server");
    }

    @Override
    public Client getClient(){
        return (ClientImpl)map.get("client");
    }

    @Override
    public DBStore getDbStore(){
        return (DBStoreImpl)map.get("dbstore");
    }

    @Override
    public Gather getGather(){
        return (GatherImpl)map.get("gather");
    }

    @Override
    public Backup getBackup(){
        return (BackupImpl)map.get("backup");
    }
}
